package pl.pw.mkmw.pnganimator.image;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;

/**
 * @author MK
 */
public class DataCompressor {

    private static final Logger LOG = Logger.getLogger(DataCompressor.class.getName());

    /** 
     * Compresses Image to byte array. Uses Deflate algorithm.
     */
    public static byte[] deflate(SImage s) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream(65536);
        DeflaterOutputStream dos = new DeflaterOutputStream(baos, new Deflater(6));
        BufferedOutputStream bos = new BufferedOutputStream(dos);

        //estimated uncompressed length (Image dimensions + filter byte each line).
        int uncompressedLength = s.getHeight()*(s.getWidth()*4 + 1);
        LOG.log(Level.INFO, "Compressing, uncompressed size : {0}", uncompressedLength);
        
        byte[] compressed = null;
        try {
            for (int y = 0; y < s.getHeight(); y++) {
                bos.write(0); //write scanline filter type
                for (int x = 0; x < s.getWidth(); x++) {
                    bos.write(s.getRed(x, y));
                    bos.write(s.getGreen(x, y));
                    bos.write(s.getBlue(x, y));
                    bos.write(s.getAlpha(x, y));
                }
            }
            bos.close();
            
            compressed = baos.toByteArray();

            double ratio = Math.floor(((double)compressed.length/uncompressedLength)*10000.0)/100; //estimated percentage after deflate
            LOG.log(Level.INFO, "Compressing, compressed size : {0} ({1}% after deflate)", new Object[]{compressed.length, ratio});

        } catch (IOException ex) {
            LOG.log(Level.SEVERE, null, ex);
        }

        return compressed;
    }

}
